-----------------------------------------------------------------------------
--
-- Module      :  Main
-- Copyright   :
-- License     :  AllRightsReserved
--
-- Maintainer  :
-- Stability   :
-- Portability :
--
-- |
--
-----------------------------------------------------------------------------
import Data.List
import Control.Monad

chessBoard :: Int -> [(Int, Int)]
chessBoard n = [(a,b) | a <- [1..n], b <- [1..n]]

initAndGenerate :: [(Int, Int)] -> [[(Int, Int)]]
initAndGenerate list = snd (generateMaxPositions list [])

-- List of available places, current position list, list of positions with max figures
generateMaxPositions :: [(Int, Int)] -> [(Int, Int)] -> (Int, [[(Int, Int)]])
generateMaxPositions [] positions = (length positions, [positions])
generateMaxPositions (el@(x, y):xs) positions = let
    currentPositionList = generateMaxPositions (filter (\(i,j) -> abs (x-i) /= abs (y-j)) xs) (el:positions)
    followingPositionList = generateMaxPositions xs positions
    lengthCurrent = fst currentPositionList
    lengthFollowing = fst followingPositionList
    in if lengthCurrent == lengthFollowing
        then
            (lengthCurrent, snd currentPositionList ++ snd followingPositionList)
        else
            max currentPositionList followingPositionList

solve :: Int -> [[(Int, Int)]]
solve n = [b ++ w | b <- initAndGenerate black, w <- initAndGenerate white]
    where board = chessBoard n
          (black, white) = partition (\(x,y) -> even (x+y)) board

nicePrint :: Int -> [[(Int, Int)]] -> IO ()
nicePrint n list = do
    forM_ list (\p ->
        let symbs = [s | s <- map (\(w,h) -> if h > n then '\n' else if (h,w) `elem` p
                      then 'O' else '_') [(w, h) | w <-[1..n], h <- [1..n+1]]]
        in putStrLn symbs
        )
    print $ length list

main = do
    let n = 3
    nicePrint n $ solve n
